package com.xlabs.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.xlabs.client.ChromelessPlayer.PlayerListener;
import com.xlabs.client.ChromelessPlayer.PlayerState;
import com.xlabs.client.shared.JeeqsRequestFactory;

/**
 * The main entry point for Skulgia.
 */
public class Skulgia implements EntryPoint, PlayerListener
{

	/**
	 * Global request factory.
	 */
	private static JeeqsRequestFactory RequestFactory;

	/**
	 * The main panel.
	 */
	private FlowPanel pagePanel;
	
	/**
	 * The content panel.
	 */
	private FlowPanel contentPanel = new FlowPanel();
	
	/**
	 * youtube search widget.
	 */
	private YoutubeAdapter youtubeAdapterWidget = new YoutubeAdapter("Player1",
			this);

	/**
	 * The comment box.
	 */
	private TextArea commentBox = new TextArea();

	/**
	 * The comment panel.
	 */
	private VerticalPanel commentPanel = new VerticalPanel();
	
	/**
	 * Current video id.
	 */
	private String currentVideoId;

	/**
	 * Scrollbar for comments.
	 */
	private Questions questions;
	
	/**
	 * Comment view panel.
	 */
	private VerticalPanel questionView = new VerticalPanel();

	/**
	 * Schollbar for coversations.
	 */
	private Conversation conversation = new Conversation();

	/**
	 * header;
	 */
	private Header header;
	
	/**
	 * {@link CommentingService} instance used in this class.
	 */
	private static CommentingServiceAsync commentingService;

	/**
	 * Global event bus
	 */
	private static EventBus eventBus = new SimpleEventBus();
	
	/**
	 * Returns event bus.
	 * @return event bus.
	 */
	public static EventBus getEventBus()
	{
		return eventBus;
	}

	/**
	 * On Module Load.
	 */
	public void onModuleLoad()
	{
		initializeOuterPanels();
		initializeHeader();
		initializeContentPanel();
		
		loadFirstPageQuestions();
		RootLayoutPanel.get().addStyleName("rootLayoutPanel");
		RootLayoutPanel.get().add(pagePanel);
		// GWT sets the parent overflow to hidden.
		pagePanel.getElement().getParentElement().getStyle().setOverflow(Overflow.AUTO);
	}

	/**
	 * Initializes the content panel.
	 */
	private void initializeContentPanel()
	{
		contentPanel.addStyleName("contentPanel");
		contentPanel.setWidth(Window.getClientWidth() * 80 / 100 + "px");
		pagePanel.add(contentPanel);
		initializeCommentingView();
		initializeVideoPanel();
	}

	/**
	 * Initializes the header.
	 */
	private void initializeHeader()
	{
		this.header = new Header();

		this.pagePanel.add(this.header);
	}

	/**
	 * Initializes comment view.
	 */
	private void initializeCommentingView()
	{
		FlowPanel forumOuterPanel = new FlowPanel();
		VerticalPanel forumPanel = new VerticalPanel();
		
		forumPanel.setWidth("100%");
		forumPanel.add(questionView);
		forumPanel.add(conversation);
		
		questions = new Questions(youtubeAdapterWidget, conversation);

		questionView.add(questions);
		questionView.setWidth("100%");
		
		forumOuterPanel.add(forumPanel);
		forumOuterPanel.setTitle("forumOuterPanel");
		forumOuterPanel.addStyleName("forumOuterPanel");
		
		contentPanel.add(forumOuterPanel);
	}

	/**
	 * Initializes video panel.
	 */
	private void initializeVideoPanel()
	{
		FlowPanel videoOuterPanel = new FlowPanel();
		VerticalPanel videoPanel = new VerticalPanel();
		HorizontalPanel controlButtonsLayout = new HorizontalPanel();
		HorizontalPanel paddingPanelStart = new HorizontalPanel();
		HorizontalPanel paddingPanelEnd = new HorizontalPanel();
		VerticalPanel displayAndControls = new VerticalPanel();
		
		paddingPanelStart.setHeight("5px");
		paddingPanelEnd.setHeight("5px");
		
		displayAndControls.setWidth("100%");
		displayAndControls.addStyleName("Group");
		displayAndControls.add(this.youtubeAdapterWidget);
		displayAndControls.add(paddingPanelStart);
		displayAndControls.add(controlButtonsLayout);
		displayAndControls.add(paddingPanelEnd);
		
		initializeControlButtons(controlButtonsLayout);
		
		videoPanel.add(displayAndControls);
		videoPanel.setWidth("100%");
		videoPanel.add(this.commentPanel);
		
		videoOuterPanel.add(videoPanel);
		videoOuterPanel.setTitle("videoOuterPanel");
		videoOuterPanel.addStyleName("videoOuterPanel");
		
		contentPanel.add(videoOuterPanel);
		
		initializeQuestionPanel();
	}

	/**
	 * Initializes comment panel.
	 */
	private void initializeQuestionPanel()
	{

		HorizontalPanel paddingPanelSeparator = new HorizontalPanel();
		paddingPanelSeparator.setHeight("5px");

		commentBox.setHeight("100px");
		commentBox.setWidth("100%");
		commentBox.setAccessKey('q');
		commentPanel.setHeight("100%");
		commentPanel.setWidth("100%");
		commentPanel.add(commentBox);

		Button submitQuestion = new Button("Ask Question");
		submitQuestion.addClickHandler(new ClickHandler()
		{

			public void onClick(ClickEvent event)
			{
				CommentingServiceAsync myService = (CommentingServiceAsync) GWT
						.create(CommentingService.class);

				AsyncCallback<Object> postCallback = new AsyncCallback<Object>()
				{
					public void onFailure(Throwable throwable)
					{
						commentBox.setText("Post Comment Failed!" + throwable
								+ "\n" + commentBox.getText());

					}

					public void onSuccess(Object o)
					{
						commentBox.setText("");
						loadFirstPageQuestions();
					}
				};

				double time = Math.max(youtubeAdapterWidget.getTime(), 0);
				myService.postQuestion(commentBox.getText(), (int) time,
						currentVideoId, postCallback);
			}
		});

		commentPanel.add(paddingPanelSeparator);
		commentPanel.setHorizontalAlignment(HorizontalPanel.ALIGN_RIGHT);
		commentPanel.add(submitQuestion);
	}

	/**
	 * Loads all comments.
	 */
	private void loadFirstPageQuestions()
	{
		questions.queryFirstPage();
	}

	/**
	 * Initializes main panel.
	 */
	private void initializeOuterPanels()
	{
		pagePanel = new FlowPanel();
		pagePanel.addStyleName("pagePanel");
	}

	/**
	 * Initializes control buttons
	 * 
	 * @param controlButtonsLayout
	 *            buttons layout.
	 */
	private void initializeControlButtons(HorizontalPanel controlButtonsLayout)
	{
		Button startButton = new Button("Start", new ClickListener()
		{
			public void onClick(Widget widget)
			{
				currentVideoId = "JPyuH4qXLZ0";
				youtubeAdapterWidget.loadVideoById(currentVideoId, 0);
			}
		});

		Button pauseButton = new Button("Pause", new ClickListener()
		{
			public void onClick(Widget widget)
			{
				youtubeAdapterWidget.pauseVideo();
				commentBox.setText("Ask your question at time : "
						+ youtubeAdapterWidget.getTime());
				commentBox.addClickListener(new ClickListener()
				{
					public void onClick(Widget widget)
					{
						commentBox.setText("");
						commentBox.removeClickListener(this);
						commentBox.setFocus(true);
					}
				});
				commentBox.setFocus(true);
			}
		});

		Button playButton = new Button("Play", new ClickListener()
		{
			public void onClick(Widget widget)
			{
				youtubeAdapterWidget.playVideo();
			}
		});

		controlButtonsLayout.add(startButton);
		controlButtonsLayout.add(pauseButton);
		controlButtonsLayout.add(playButton);
	}

	public void onReady()
	{
		// TODO Auto-generated method stub

	}

	/**
	 * see {@link PlayerListener}{@link #onStateChange(PlayerState)}
	 */
	public void onStateChange(PlayerState state)
	{
		questions.onStateChange(state);
	}

	/**
	 * Gets commenting service.
	 * @return Commenting service.
	 */
	static CommentingServiceAsync getCommentingService()
	{
		if (Skulgia.commentingService == null)
		{
			Skulgia.commentingService = (CommentingServiceAsync) GWT.create(CommentingService.class);
		}
		
		return Skulgia.commentingService;
	}

	/**
	 * Gets jeeqs request factory.
	 * @return
	 */
	public static JeeqsRequestFactory getJeeqsRequestFactory()
	{
		if (Skulgia.RequestFactory == null)	
		{
			Skulgia.RequestFactory = GWT.create(JeeqsRequestFactory.class);
	        Skulgia.RequestFactory.initialize(eventBus);
		}

		return Skulgia.RequestFactory;
	}
}
